import React, { useRef, useState, useEffect, useMemo } from 'react';
import { useFrame } from '@react-three/fiber';
import * as THREE from 'three';
import { CabinetData } from '../../../types';

interface CabinetProps {
  cabinet: CabinetData;
  isSelected?: boolean;
  onSelect: (cabinetId: string) => void;
}

const Cabinet: React.FC<CabinetProps> = ({ cabinet, isSelected = false, onSelect }) => {
  const groupRef = useRef<THREE.Group>(null);
  const [isHovered, setIsHovered] = useState(false);
  const timeRef = useRef(0);
  
  // 使用useRef缓存几何体，避免重复创建
  const cabinetGeometryRef = useRef(new THREE.BoxGeometry(0.01, 0.01, 0.01));
  const deviceGeometryRef = useRef(new THREE.BoxGeometry(0.01, 0.01, 0.01));
  const holeGeometryRef = useRef(new THREE.BoxGeometry(0.01, 0.01, 0.01));
  const cableGeometryRef = useRef(new THREE.CylinderGeometry(0.01, 0.01, 0.01, 8));
  
  // 使用useMemo缓存设备位置计算结果
  const devicePositions = useMemo(() => {
    // 随机生成3-5个设备位置
    const positions: number[] = [];
    const count = Math.floor(Math.random() * 3) + 3; // 3-5个设备
    for (let i = 0; i < count; i++) {
      positions.push(Math.floor(Math.random() * 42)); // 标准42U机柜
    }
    return positions.sort((a, b) => a - b);
  }, [cabinet.id]);
  
  // 设备类型和状态的缓存
  const deviceTypes = useMemo(() => [
    { name: '服务器', color: '#1976D2', icon: 'server' },
    { name: '交换机', color: '#388E3C', icon: 'switch' },
    { name: '存储设备', color: '#616161', icon: 'storage' },
    { name: '防火墙', color: '#7B1FA2', icon: 'firewall' },
    { name: '路由器', color: '#F57C00', icon: 'router' }
  ], []);
  
  // 状态颜色映射
  const statusColors = useMemo(() => ({
    normal: '#4CAF50',
    warning: '#FFC107',
    critical: '#F44336'
  }), []);
  
  // 电缆颜色
  const cableColors = useMemo(() => [
    '#616161', '#757575', '#9E9E9E'
  ], []);

  // 根据状态获取颜色
  const getColorByStatus = (status: string): string => {
    switch (status) {
      case 'normal':
        return '#4CAF50';
      case 'warning':
        return '#FFC107';
      case 'critical':
        return '#F44336';
      default:
        return '#2196F3';
    }
  };

  // 根据选中和悬停状态获取边框颜色
  const getBorderColor = (): string => {
    if (isSelected) {
      return '#2196F3';
    }
    if (isHovered) {
      return '#64B5F6';
    }
    return '#333333';
  };

  // 获取边框线宽
  const getBorderThickness = (): number => {
    if (isSelected) {
      return 4;
    }
    if (isHovered) {
      return 2;
    }
    return 1;
  };

  // 机柜点击处理函数
  const handleClick = (event: React.MouseEvent) => {
    event.stopPropagation();
    onSelect(cabinet.id);
  };

  // 鼠标悬停处理函数
  const handleMouseEnter = () => {
    setIsHovered(true);
  };

  const handleMouseLeave = () => {
    setIsHovered(false);
  };

  // 更新时间和动态效果
  useFrame((state) => {
    timeRef.current += 0.016;
    
    // 状态呼吸动画效果
    if (groupRef.current && (cabinet.status === 'warning' || cabinet.status === 'critical')) {
      const pulse = Math.sin(state.clock.getElapsedTime() * 2) * 0.5 + 0.5;
      const emissiveIntensity = cabinet.status === 'warning' ? 0.5 + pulse * 0.3 : 0.8 + pulse * 0.4;
      const materials = groupRef.current.children.map(child => {
        if (child instanceof THREE.Mesh && child.material instanceof THREE.MeshStandardMaterial) {
          return child.material as THREE.MeshStandardMaterial;
        }
        return null;
      }).filter(Boolean);
      materials.forEach((material) => {
        if (material) {
          material.emissiveIntensity = emissiveIntensity;
        }
      });
    }
  });

  // 计算1U的高度（基于机柜高度）
  const uHeight = cabinet.dimensions.height / 42; // 标准42U机柜

  return (
    <group
      ref={groupRef}
      position={[
        cabinet.position.x, 
        cabinet.dimensions.height / 2, // 自动计算y坐标，使机柜底部贴合地面
        cabinet.position.z
      ]}
      onClick={handleClick}
      onPointerEnter={handleMouseEnter}
      onPointerLeave={handleMouseLeave}
    >
      {/* 机柜主体 - 改进材质 */}
      <mesh
        castShadow
        receiveShadow
      >
        <boxGeometry
          args={[
            cabinet.dimensions.width,
            cabinet.dimensions.height,
            cabinet.dimensions.depth
          ]}
        />
        <meshStandardMaterial
          color={isSelected ? '#1976D2' : '#1E1E1E'}
          transparent
          opacity={0.8}
          roughness={0.6}
          metalness={0.7}
          emissive={getColorByStatus(cabinet.status)}
          emissiveIntensity={cabinet.status === 'normal' ? 0.1 : 0.3}
        />
      </mesh>

      {/* 机柜边框 - 增强视觉效果 */}
      <lineSegments>
        <edgesGeometry
          args={[
            new THREE.BoxGeometry(
              cabinet.dimensions.width,
              cabinet.dimensions.height,
              cabinet.dimensions.depth
            )
          ]}
        />
        <lineBasicMaterial
          color={getBorderColor()}
          linewidth={getBorderThickness()}
          transparent
          opacity={isSelected || isHovered ? 1 : 0.7}
        />
      </lineSegments>

      {/* 机柜顶部 - 更真实的设计 */}
      <mesh
        position={[0, cabinet.dimensions.height / 2 + 0.01, 0]}
        rotation={[0, 0, 0]}
      >
        <boxGeometry
          args={[
            cabinet.dimensions.width + 0.04,
            0.02,
            cabinet.dimensions.depth + 0.04
          ]}
        />
        <meshStandardMaterial
          color="#2A2A2A"
          roughness={0.8}
          metalness={0.6}
          emissive="#1A1A1A"
          emissiveIntensity={0.2}
        />
      </mesh>

      {/* 机柜底部 */}
      <mesh
        position={[0, -cabinet.dimensions.height / 2 - 0.01, 0]}
        rotation={[0, 0, 0]}
      >
        <boxGeometry
          args={[
            cabinet.dimensions.width + 0.04,
            0.02,
            cabinet.dimensions.depth + 0.04
          ]}
        />
        <meshStandardMaterial
          color="#2A2A2A"
          roughness={0.8}
          metalness={0.6}
        />
      </mesh>

      {/* 机柜前面板 - 增强细节 */}
      <mesh
        position={[0, 0, cabinet.dimensions.depth / 2 + 0.005]}
        rotation={[0, 0, 0]}
      >
        <boxGeometry
          args={[
            cabinet.dimensions.width - 0.02,
            cabinet.dimensions.height - 0.02,
            0.01
          ]}
        />
        <meshStandardMaterial
          color="#2D2D2D"
          roughness={0.7}
          metalness={0.3}
        />
      </mesh>

      {/* 前门边框 */}
      <lineSegments>
        <edgesGeometry
          args={[
            new THREE.BoxGeometry(
              cabinet.dimensions.width - 0.02,
              cabinet.dimensions.height - 0.02,
              0.01
            )
          ]}
        />
        <lineBasicMaterial
          color="#444444"
          linewidth={1}
        />
      </lineSegments>

      {/* U位标识 - 增加真实感 */}
      {Array.from({ length: 43 }).map((_, index) => (
        <mesh
          key={`u-mark-${index}`}
          position={[
            -cabinet.dimensions.width / 2 + 0.01,
            cabinet.dimensions.height / 2 - index * uHeight,
            cabinet.dimensions.depth / 2
          ]}
          rotation={[0, 0, 0]}
        >
          <boxGeometry args={[0.005, 0.001, 0.005]} />
          <meshStandardMaterial
            color="#666666"
            roughness={0.5}
            metalness={0.3}
          />
        </mesh>
      ))}

      {/* 前面板通风孔 - 改进设计 */}
      <group position={[0, 0, cabinet.dimensions.depth / 2 + 0.015]}>
        {/* 左侧通风孔阵列 */}
        {Array.from({ length: 12 }).map((_, rowIndex) => (
          Array.from({ length: 3 }).map((_, colIndex) => (
            <mesh
              key={`vent-left-${rowIndex}-${colIndex}`}
              position={[
                -cabinet.dimensions.width / 4 + colIndex * (cabinet.dimensions.width / 8),
                cabinet.dimensions.height / 2 - 0.05 - rowIndex * (cabinet.dimensions.height / 15),
                0
              ]}
            >
              <boxGeometry
                args={[
                  cabinet.dimensions.width / 12,
                  cabinet.dimensions.height / 30,
                  0.003
                ]}
              />
              <meshStandardMaterial
                color="#2A2A2A"
                roughness={0.8}
                metalness={0.2}
              />
            </mesh>
          ))
        ))}
        
        {/* 右侧通风孔阵列 */}
        {Array.from({ length: 12 }).map((_, rowIndex) => (
          Array.from({ length: 3 }).map((_, colIndex) => (
            <mesh
              key={`vent-right-${rowIndex}-${colIndex}`}
              position={[
                0 + colIndex * (cabinet.dimensions.width / 8),
                cabinet.dimensions.height / 2 - 0.05 - rowIndex * (cabinet.dimensions.height / 15),
                0
              ]}
            >
              <boxGeometry
                args={[
                  cabinet.dimensions.width / 12,
                  cabinet.dimensions.height / 30,
                  0.003
                ]}
              />
              <meshStandardMaterial
                color="#2A2A2A"
                roughness={0.8}
                metalness={0.2}
              />
            </mesh>
          ))
        ))}
      </group>

      {/* 模拟安装的设备 - 增加真实感 */}
      {devicePositions.map((uPosition, index) => {
        // 随机设备高度 1-4U
        const deviceHeightU = Math.floor(Math.random() * 4) + 1;
        const deviceHeight = deviceHeightU * uHeight;
        
        // 确保设备不会超出机柜顶部
        const adjustedUPosition = Math.min(uPosition, 42 - deviceHeightU);
        const deviceY = cabinet.dimensions.height / 2 - adjustedUPosition * uHeight - deviceHeight / 2;
        
        // 设备尺寸调整，确保完全在机柜内部
        const deviceWidth = cabinet.dimensions.width * 0.85;
        const deviceDepth = cabinet.dimensions.depth * 0.7;
        
        // 缓存几何体
        deviceGeometryRef.current.dispose();
        deviceGeometryRef.current = new THREE.BoxGeometry(deviceWidth, deviceHeight, deviceDepth);
        
        const deviceType = deviceTypes[index % deviceTypes.length];
        const deviceColor = deviceType.color;
        const deviceName = deviceType.name;
        
        // 设备状态随机化，增强真实感
        const deviceStatus = Math.random() > 0.15 ? 'normal' : (Math.random() > 0.5 ? 'warning' : 'critical');
        
        return (
          <group key={`device-${index}`}>            
            {/* 设备主体 - 调整位置和尺寸 */}
            <mesh
              position={[0, deviceY, -cabinet.dimensions.depth * 0.2]}
            >
              <boxGeometry args={[deviceWidth, deviceHeight, deviceDepth]} />
              <meshStandardMaterial
                color={deviceColor}
                roughness={0.5}
                metalness={0.6}
                emissive={deviceStatus === 'normal' ? deviceColor : getColorByStatus(deviceStatus)}
                emissiveIntensity={deviceStatus === 'normal' ? 0.2 : 0.4}
              />
            </mesh>
            
            {/* 设备前面板 - 调整位置，确保在机柜内部 */}
            <mesh
              position={[0, deviceY, -cabinet.dimensions.depth * 0.2 + deviceDepth / 2 + 0.005]}
            >
              <boxGeometry
                args={[
                  deviceWidth * 0.95,
                  deviceHeight - 0.01,
                  0.01
                ]}
              />
              <meshStandardMaterial
                color="#212121"
                roughness={0.8}
                metalness={0.4}
              />
            </mesh>
            
            {/* 设备指示灯 - 调整位置，确保在机柜内部 */}
            <mesh
              position={[
                deviceWidth * 0.35,
                deviceY + deviceHeight / 3,
                -cabinet.dimensions.depth * 0.2 + deviceDepth / 2 + 0.01
              ]}
            >
              <sphereGeometry args={[0.005]} />
              <meshStandardMaterial
                color={deviceStatus === 'normal' ? '#4CAF50' : getColorByStatus(deviceStatus)}
                emissive={deviceStatus === 'normal' ? '#4CAF50' : getColorByStatus(deviceStatus)}
                emissiveIntensity={1.5}
                roughness={0.1}
                metalness={0.2}
              />
            </mesh>
            
            {/* 设备小指示灯 - 增加细节，确保在机柜内部 */}
            <mesh
              position={[
                deviceWidth * 0.35,
                deviceY + deviceHeight / 3 - 0.015,
                -cabinet.dimensions.depth * 0.2 + deviceDepth / 2 + 0.01
              ]}
            >
              <sphereGeometry args={[0.003]} />
              <meshStandardMaterial
                color="#03A9F4"
                emissive="#03A9F4"
                emissiveIntensity={1.0}
                roughness={0.1}
                metalness={0.2}
              />
            </mesh>
            
            {/* 设备前面板把手 - 增强真实感，确保在机柜内部 */}
            <mesh
              position={[
                deviceWidth * 0.45,
                deviceY,
                -cabinet.dimensions.depth * 0.2 + deviceDepth / 2 + 0.01
              ]}
            >
              <cylinderGeometry args={[0.003, 0.003, 0.015, 8]} />
              <meshStandardMaterial
                color="#616161"
                roughness={0.8}
                metalness={0.6}
              />
            </mesh>
          </group>
        );
      })}
      
      {/* 电缆连接 - 增强真实感 */}
      <group>
        {Array.from({ length: 8 }).map((_, index) => {
          const randomY = (Math.random() - 0.5) * cabinet.dimensions.height * 0.7;
          const randomZ = -cabinet.dimensions.depth * 0.3 - Math.random() * cabinet.dimensions.depth * 0.4;
          const thickness = 0.003 + Math.random() * 0.002;
          
          // 电缆颜色多样化
          const cableColors = ['#616161', '#757575', '#9E9E9E'];
          const cableColor = cableColors[index % cableColors.length];
          
          return (
            <mesh 
              key={`cable-${index}`}
              position={[cabinet.dimensions.width * 0.3, randomY, randomZ]}
              rotation={[0, Math.PI / 2, Math.random() * 0.1]}
            >
              <cylinderGeometry args={[thickness, thickness, cabinet.dimensions.width * 0.2, 8]} />
              <meshStandardMaterial
                color={cableColor}
                roughness={0.9}
                metalness={0.1}
                transparent
                opacity={0.6}
              />
            </mesh>
          );
        })}
      </group>
      
      {/* 机柜侧面通风孔 - 使用更少的几何体 */}
      <group position={[cabinet.dimensions.width / 2, 0, 0]}>
        {Array.from({ length: 8 }).map((_, rowIndex) => {
          return Array.from({ length: 4 }).map((_, colIndex) => {
            const zPosition = -cabinet.dimensions.depth / 2 + 0.1 + colIndex * (cabinet.dimensions.depth / 5);
            const yPosition = -cabinet.dimensions.height / 2 + 0.15 + rowIndex * (cabinet.dimensions.height / 9);
            
            // 缓存几何体
            holeGeometryRef.current.dispose();
            holeGeometryRef.current = new THREE.BoxGeometry(0.003, 0.03, 0.03);
            
            return (
              <mesh 
                key={`side-vent-${rowIndex}-${colIndex}`}
                position={[0.005, yPosition, zPosition]}
              >
                <boxGeometry args={[0.003, 0.03, 0.03]} />
                <meshStandardMaterial
                  color="#2A2A2A"
                  roughness={0.8}
                  metalness={0.2}
                />
              </mesh>
            );
          });
        })}
      </group>

      {/* 机柜标签 - 改进设计 */}
      <mesh
        position={[0, cabinet.dimensions.height / 2 + 0.03, 0]}
        rotation={[-Math.PI / 2, 0, 0]}
      >
        <planeGeometry
          args={[
            cabinet.dimensions.width * 0.8,
            cabinet.dimensions.depth * 0.8
          ]}
        />
        <meshStandardMaterial
          color="#1E1E1E"
          roughness={0.5}
          metalness={0.7}
          transparent
          opacity={0.9}
        />
      </mesh>
      
      {/* 标签边框 */}
      <lineSegments>
        <edgesGeometry
          args={[
            new THREE.PlaneGeometry(
              cabinet.dimensions.width * 0.8,
              cabinet.dimensions.depth * 0.8
            )
          ]}
        />
        <lineBasicMaterial
          color="#424242"
          linewidth={1}
        />
      </lineSegments>

      {/* 状态指示器 - 增强科技感 */}
      <group
        position={[
          cabinet.dimensions.width / 2 + 0.05,
          cabinet.dimensions.height / 2,
          0
        ]}
      >
        {/* 指示器底座 */}
        <mesh>
          <cylinderGeometry args={[0.07, 0.07, 0.03, 8]} />
          <meshStandardMaterial
            color="#212121"
            roughness={0.8}
            metalness={0.6}
          />
        </mesh>
        
        {/* 指示器灯光 */}
        <mesh position={[0, 0.03, 0]}>
          <sphereGeometry args={[0.05]} />
          <meshStandardMaterial
            color={getColorByStatus(cabinet.status)}
            emissive={getColorByStatus(cabinet.status)}
            emissiveIntensity={cabinet.status === 'normal' ? 0.7 : cabinet.status === 'warning' ? 1.0 : 1.5}
            roughness={0.1}
            metalness={0.3}
            transparent
            opacity={0.9}
          />
        </mesh>
      </group>
      
      {/* 动态数据连接线 - 增强科技感 */}
      {isSelected && (
        <group>
          {Array.from({ length: 5 }).map((_, index) => {
            const randomY = (Math.random() - 0.5) * cabinet.dimensions.height * 0.8;
            const randomDelay = index * 0.2;
            const pulse = 0.5 + 0.5 * Math.sin((timeRef.current + randomDelay) * 2);
            
            const startX = cabinet.dimensions.width / 2 + 0.05;
            const startY = randomY;
            const endX = cabinet.dimensions.width / 2 + 0.2 + pulse * 0.05;
            const endY = randomY + (Math.sin(timeRef.current * 1.5) * 0.05);
            
            return (
              <line
                key={`data-line-${index}`}
                x1={startX}
                y1={startY}
                x2={endX}
                y2={endY}
              >
                <lineBasicMaterial
                  color="#00f0ff"
                  linewidth={1}
                  transparent
                  opacity={0.3 + pulse * 0.3}
                />
              </line>
            );
          })}
        </group>
      )}
    </group>
  );
};

export default React.memo(Cabinet);